# -*- coding: UTF-8 -*-
# @description : python
# @Author : zyl
# @contact : zyl@mxsoft.com
# @Time : 2021/9/29 18:00
# @Remark: IP网络 数据库层
import logging
import json

from bsmiddle import *
from index import _
from mxsoftpy import DB
from mxsoftpy.TreeDB import symbol_map
from mxsoftpy.db_def.def_type import type_map
from mxsoftpy.exception import ParamsError, DataError, DBError

from db.common.NetworkManage.IpAM import modify
from utils.conf.mxconfig import MxConfig
from mxsoftpy.db_def.def_tree import TRDB_OPKF_OPENEXIST, TRDB_OPKF_DOTPATH


class IpNetworkDB(DB):

    def GetCompany(self, **kwargs):
        if 'company' not in kwargs:
            raise DataError(_('获取公司失败'))
        return kwargs['company']

    def check_label(self, label):
        """
        检查名称是否重复
        :param label: 名称 字符串
        :return:
        """
        QIS = [{"name": "label", "nCondition": symbol_map['e'], "vLiData": label,
                "vLiDataType": type_map['str']}]
        daataCount = self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', [], 0, 0)
        if daataCount > 0:
            return True
        return False

    def GetTsInfo(self):
        """
        获取TS信息
        :return: TS字典
        """
        subkey = self.tree.open('Co', '', file='master', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        ccuids = list()
        for key in subkey:
            self.tree.exec_tree('Treedb_ReopenSubKey', key, TRDB_OPKF_OPENEXIST)
            sskey = list()
            self.tree.exec_tree('Treedb_GetAllSubKeys', sskey)
            if 'CCUList' in sskey:
                self.tree.exec_tree('Treedb_ReopenSubKey', key + '\\CCUList', TRDB_OPKF_OPENEXIST)
                ccuid = list()
                self.tree.exec_tree('Treedb_GetAllSubKeys', ccuid)
                if ccuid:
                    ccuids.extend(ccuid)
        TsData = dict()
        for id in ccuids:
            TsData[id] = []
            self.tree.open(id, '1', file='ccubase', host=MxConfig.HOST, port=MxConfig.PORT)
            res_dict = {}
            self.tree.exec_bs('bs_treedb_get_properties', [], res_dict)
            self.tree.exec_tree('Treedb_ReopenSubKey', '1.TS', TRDB_OPKF_DOTPATH)
            TsInfo = {}
            self.tree.exec_bs('bs_treedb_get_subkey_properties', [], ['mx_fixtsserver', 'oldid'], TsInfo)
            for oid, val in TsInfo.items():
                if id in TsData:
                    TsData[id].append(
                        {'oldid': oid, 'mxGuid': res_dict['mxGuid'], 'mx_fixtsserver': val['mx_fixtsserver']})
        return TsData

    # @modify
    def create(self, **kwargs) -> int:
        """
        添加IP网络信息
        :param kwargs:
        :return:
        """
        TsInfo_dict = self.GetTsInfo()
        scompany = self.GetCompany(**kwargs)
        try:
            subkey = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
            self.tree.begin()
            if scompany not in subkey:
                self.tree.exec_tree('Treedb_InsertSubKey', scompany, TRDB_OPKF_OPENEXIST)
                self.tree.exec_tree('Treedb_ReopenSubKey', scompany, TRDB_OPKF_OPENEXIST)
                self.tree.exec_bs('bs_treedb_insert_subkey', 'Net', TRDB_OPKF_OPENEXIST)
            sub_path = scompany + '\\Net'
            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path, TRDB_OPKF_OPENEXIST)
            if self.check_label(kwargs['label']):
                raise Exception(_('名称已存在'))
            kwargs.pop('company')
            ts_list = json.loads(kwargs['ts'])
            kwargs.pop('ts')
            items = list()
            for k, v in kwargs.items():
                if k in ['parent', 'state', 'type']:
                    items.append((k, int(v), 'int'))
                else:
                    items.append((k, v))
            items.append(('state', 0, 'int'))
            res_str = self.tree.exec_tree('Treedb_InsertSubKey', '', TRDB_OPKF_OPENEXIST)
            sub_path += '\\' + res_str
            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path, TRDB_OPKF_OPENEXIST)
            items.append(('id', res_str))
            self.tree.insert_items(items)
            self.tree.exec_bs('bs_treedb_insert_subkey', 'ts', TRDB_OPKF_OPENEXIST)
            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\ts', TRDB_OPKF_OPENEXIST)
            if kwargs['TsId'].find(';') != -1:
                for val in ts_list:
                    for tsid in TsInfo_dict[val['ccuid']]:
                        if val['mx_fixtsserver'] in [tsid['mx_fixtsserver'], tsid['mxGuid']]:
                            TsData = [('id', tsid['oldid']), ('mxlabel', val['mxlabel']),
                                      ('mx_fixtsserver', val['mx_fixtsserver']),
                                      ('mxGuid', tsid['mxGuid']), ('ccuid', val['ccuid'])]
                            res_str = self.tree.insert_key_items(TsData)
            else:
                for val in ts_list:
                    for tsid in TsInfo_dict[val['ccuid']]:
                        if val['mx_fixtsserver'] in [tsid['mx_fixtsserver'], tsid['mxGuid']]:
                            TsData = [('id', tsid['oldid']), ('mxlabel', val['mxlabel']),
                                      ('mx_fixtsserver', val['mx_fixtsserver']),
                                      ('mxGuid', tsid['mxGuid']), ('ccuid', val['ccuid'])]
                            res_str = self.tree.insert_key_items(TsData)
            self.tree.commit()
            return res_str
        except DBError as e:
            self.tree.rollback()
            logging.error('添加IP信息失败, %s' % str(e))
            raise Exception(str(e))

    # @modify
    def IpNetwork_dict(self, **kwargs) -> dict:
        """
        返回所有IP网络数据
        :param kwargs:  参数字典
        :return: IP数据字典
        """
        scompany = self.GetCompany(**kwargs)
        path = scompany + '\\Net'
        sub_key = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if scompany not in sub_key:
            return list()
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                "vLiDataType": type_map['int']}]
        subQIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                   "vLiDataType": type_map['int']}]
        condition = '0'
        key = []
        if 'label' in kwargs:
            if kwargs['label']:
                label = kwargs['label']
                QIS.append({"name": "label", "nCondition": symbol_map['nclike'], "vLiData": '*' + label + '*',
                            "vLiDataType": type_map['str']})
                condition += ' and 1'
        if 'id' in kwargs:
            if kwargs['id']:
                QIS.append({"name": "id", "nCondition": symbol_map['e'], "vLiData": kwargs['id'],
                            "vLiDataType": type_map['str']})
                condition += ' and 1'
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, condition, key, 0, 0)
        result = {}
        if len(key) > 0:
            self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)
            for key, val in result.items():
                self.tree.exec_bs('bs_treedb_open_subkey', path + '\\' + key, TRDB_OPKF_OPENEXIST)
                subkey = []
                self.tree.exec_bs('bs_treedb_get_subkeys', subkey)
                if subkey:
                    for skey in subkey:
                        if skey == 'ts':
                            continue
                        if 'id' in kwargs and skey == 'SubNet':
                            continue
                        self.tree.exec_bs('bs_treedb_open_subkey', path + '\\' + key + '\\' + skey, TRDB_OPKF_OPENEXIST)
                        ssubkey = []
                        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', subQIS, '', ssubkey, 0, 0)
                        if ssubkey:
                            subResult = {}
                            self.tree.exec_bs('bs_treedb_get_subkey_properties', ssubkey, [], subResult)
                            val[skey] = subResult
        return result

    # @modify
    def update_check_label(self, sub_path, label, id):
        """
        更新检查名称重复
        :param sub_path:  数据库路径 字符串
        :param label:  名称 字符串
        :param id:  主键ID 字符串
        :return: 布尔值
        """
        # 检查名称是否重复
        self.tree.open('Co', sub_path, file='ipctrl',
                       host=MxConfig.HOST, port=MxConfig.PORT)
        QIS = [{"name": "label", "nCondition": symbol_map['e'], "vLiData": label,
                "vLiDataType": type_map['str']},
               {"name": "id", "nCondition": symbol_map['ne'], "vLiData": id,
                "vLiDataType": type_map['str']}]
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '0 and 1', key, 0, 0)
        if key:
            raise Exception(_('名称已存在'))

    # @modify
    def update(self, **kwargs) -> str:
        """
        更新网络数据
        :param kwargs: 数据字典
        """
        TsInfo_dict = self.GetTsInfo()
        scompany = self.GetCompany(**kwargs)
        try:
            self.update_check_label(scompany + '\\Net', kwargs['label'], kwargs['id'])
            sub_path = scompany + '\\Net\\' + kwargs['id']
            data = [('TsId', kwargs['TsId']), ('label', kwargs['label'])]
            ts = self.tree.open('Co', sub_path, file='ipctrl',
                                host=MxConfig.HOST, port=MxConfig.PORT).items('TsId')
            self.tree.begin()
            new_TsId = kwargs['TsId'].split(';')
            old_TSId = ts['TsId'].split(';')
            sbool = set(old_TSId).issubset(set(new_TsId))
            if sbool is False:
                SubNetkeys = list()
                self.tree.exec_tree('Treedb_GetAllSubKeys', SubNetkeys)
                if 'SubNet' in SubNetkeys:
                    self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\SubNet', TRDB_OPKF_OPENEXIST)
                    self.tree.exec_bs('bs_treedb_delete_key')
                    ClearSubNet(scompany, kwargs['id'])
                if 'IP' in SubNetkeys:
                    self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\IP', TRDB_OPKF_OPENEXIST)
                    self.tree.exec_bs('bs_treedb_delete_key')
                    ClearIp(scompany, kwargs['id'])
            self.tree.open('Co', sub_path, file='ipctrl',
                           host=MxConfig.HOST, port=MxConfig.PORT).insert_items(data)

            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\ts', TRDB_OPKF_OPENEXIST)
            keys = list()
            self.tree.exec_tree('Treedb_GetAllSubKeys', keys)
            for key in keys:
                self.tree.exec_tree('Treedb_DeleteSubKey', key)
            print(keys)
            ts_list = json.loads(kwargs['ts'])
            kwargs.pop('ts')
            if kwargs['TsId'].find(';') != -1:
                for val in ts_list:
                    for tsid in TsInfo_dict[val['ccuid']]:
                        if val['mx_fixtsserver'] in [tsid['mx_fixtsserver'], tsid['mxGuid']]:
                            TsData = [('id', tsid['oldid']), ('mxlabel', val['mxlabel']),
                                      ('mx_fixtsserver', val['mx_fixtsserver']),
                                      ('mxGuid', tsid['mxGuid']),
                                      ('ccuid', val['ccuid'])]
                            res_str = self.tree.insert_key_items(TsData)
            else:
                for val in ts_list:
                    for tsid in TsInfo_dict[val['ccuid']]:
                        if val['mx_fixtsserver'] in [tsid['mx_fixtsserver'], tsid['mxGuid']]:
                            TsData = [('id', tsid['oldid']), ('mxlabel', val['mxlabel']),
                                      ('mx_fixtsserver', val['mx_fixtsserver']),
                                      ('mxGuid', tsid['mxGuid']),
                                      ('ccuid', val['ccuid'])]
                            res_str = self.tree.insert_key_items(TsData)
            self.tree.commit()
            return res_str
        except DBError as e:
            self.tree.rollback()
            logging.error('更新数据失败, %s' % str(e))
            raise Exception(_(str(e)))

    # @modify
    def ignore(self, **kwargs) -> str:
        """
        忽略网络
        :param id: 主键ID 字符串
        """
        scompany = self.GetCompany(**kwargs)
        sub_path = scompany + '\\Net\\' + kwargs['id']
        # 获取网络下子网
        keys = self.tree.open('Co', sub_path, file='ipctrl',
                              host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if 'SubNet' in keys:
            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\SubNet', TRDB_OPKF_OPENEXIST)
            subResult = {}
            self.tree.exec_bs('bs_treedb_get_subkey_properties', [], [], subResult)
            if subResult:
                for key, val in subResult.items():
                    self.tree.open('Co', sub_path + '\\SubNet\\' + key, file='ipctrl', host=MxConfig.HOST,
                                   port=MxConfig.PORT).insert_item('state', 1)
        if 'group' in keys:
            self.tree.exec_tree('Treedb_ReopenSubKey', sub_path + '\\group', TRDB_OPKF_OPENEXIST)
            self.tree.exec_bs('bs_treedb_delete_key')
        try:
            self.tree.open('Co', scompany + '\\Net\\' + kwargs['id'], file='ipctrl',
                           host=MxConfig.HOST, port=MxConfig.PORT).insert_item('state', 1)
        except DBError as e:
            logging.error('网络忽略失败, %s' % str(e))
            raise ParamsError(_('更新数据失败, %s' % str(e)))
        return kwargs['id']

    # @modify
    def delete(self, **kwargs) -> int:
        """
        删除网络
        :param kwargs: 参数字典
        :return:
        """
        scompany = self.GetCompany(**kwargs)
        if kwargs['id']:  # 只有列表中有值才执行操作，防止删除整个视频组
            try:
                self.tree.open('Co',f'{scompany}\\AccountId\\110', file='ipctrl',
                                       host=MxConfig.HOST, port=MxConfig.PORT)
                res = self.tree.items()['type']
            except:
                res = 0
            if res:
                raise DataError(_('正在扫描无法删除'))
            try:
                if kwargs['id'].find(';') == -1:
                    self.tree.open('Co', scompany + '\\Net\\' + kwargs['id'], file='ipctrl',
                                   host=MxConfig.HOST, port=MxConfig.PORT).delete()
                else:
                    delIds_list = kwargs['id'].split(';')
                    for id in delIds_list:
                        self.tree.open('Co', scompany + '\\Net\\' + id, file='ipctrl', host=MxConfig.HOST,
                                       port=MxConfig.PORT).delete()
            except DBError as e:
                logging.error('删除网络失败, %s' % str(e))
                raise DBError(str(e))
        return kwargs['id']

    # @modify
    def retrieve(self, **kwargs):
        """
        回显数据
        :param kwargs:
        :return:
        """
        scompany = self.GetCompany(**kwargs)
        return self.tree.open('Co', scompany + '\\Net\\' + kwargs['id'], file='ipctrl',
                              host=MxConfig.HOST, port=MxConfig.PORT).items()

    # @modify
    def GroupSet(self, **kwargs):
        """
        网络组添加
        :return:
        """
        scompany = self.GetCompany(**kwargs)
        sub_path = scompany + '\\Net\\' + kwargs['id']
        try:
            sub_key = self.tree.open('Co', sub_path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
            self.tree.begin()
            if 'group' not in sub_key:
                self.tree.insert_sub_keys('group')
            kwargs['state'] = 0
            id = kwargs['id']
            kwargs.pop('company')
            kwargs.pop('id')
            self.tree.open('Co', sub_path + '\\group', file='ipctrl')
            # 检查组是否重复
            QIS = [{"name": "name", "nCondition": symbol_map['e'], "vLiData": kwargs['name'],
                    "vLiDataType": type_map['str']}]
            condition = '0'
            if 'groupId' in kwargs:
                QIS.append({"name": "groupId", "nCondition": symbol_map['ne'], "vLiData": kwargs['groupId'],
                            "vLiDataType": type_map['str']})
                condition += ' and 1'
            key = []
            self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, condition, key, 0, 0)
            if key:
                raise Exception('名称已存在')
            if 'groupId' in kwargs:
                self.tree.open('Co', sub_path + '\\group\\' + kwargs['groupId'], file='ipctrl').insert_item('name',
                                                                                                            kwargs[
                                                                                                                'name'])
                self.tree.commit()
                ModifyNetGroup(scompany, id, kwargs['groupId'], 2)
            else:
                res = self.tree.exec_tree('Treedb_InsertSubKey', '', TRDB_OPKF_OPENEXIST)
                sub_path += '\\group\\' + res
                self.tree.exec_tree('Treedb_ReopenSubKey', sub_path, TRDB_OPKF_OPENEXIST)
                self.tree.insert_items([(k, v) for k, v in kwargs.items()])
                self.tree.insert_item('groupId', res, 'str')
                self.tree.commit()
                # 通知bsmiddle
                ModifyNetGroup(scompany, id, res, 0)
            return True
        except DBError as e:
            self.tree.rollback()
            logging.error('添加网络组失败, %s' % str(e))
            raise Exception(str(e))

    def loopData(self, data, groupid, result):
        """
        递归获取数据
        :param data: 数据字典
        :param groupid: 组ID
        :param result: 返回数据字典
        :return:
        """
        for key, val in data.items():
            if val['parent'] == groupid:
                result.append(key)
                self.loopData(data, key, result)

    def GetGroup(self, path, groupid):
        """
        获取分组下级
        :param path: 路径
        :param groupid: 组ID
        :return:
        """
        self.tree.exec_tree('Treedb_ReopenSubKey', path, TRDB_OPKF_OPENEXIST)
        keys = list()
        self.tree.exec_tree('Treedb_GetAllSubKeys', keys)
        if 'group' not in keys:
            return list()
        self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\group', TRDB_OPKF_OPENEXIST)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                "vLiDataType": type_map['int']}]
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)
        data = []
        if key:
            result = {}
            self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)
            self.loopData(result, groupid, data)
            data.append(groupid)
        return data

    def GetSubnet(self, path, group):
        """
        根据组ID获取子网列表
        :param path: 路径
        :param group: 组列表
        :return:
        """
        self.tree.exec_tree('Treedb_ReopenSubKey', path, TRDB_OPKF_OPENEXIST)
        keys = list()
        self.tree.exec_tree('Treedb_GetAllSubKeys', keys)
        if 'SubNet' not in keys:
            return list()
        self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\SubNet', TRDB_OPKF_OPENEXIST)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                "vLiDataType": type_map['int']}]
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)
        data = []
        if key:
            result = {}
            self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)
            for key, val in result.items():
                if 'GroupId' in val:
                    if val['GroupId'] in group:
                        data.append(key)
        return data

    # @modify
    def GroupDelete(self, **kwargs):
        """
        删除网络组
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        # 检查分组下是否存在子网
        path = company + '\\Net\\' + str(kwargs['id'])
        sub_key = self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        data = self.GetGroup(path, kwargs['groupId'])
        if 'SubNet' in sub_key:
            self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\SubNet', TRDB_OPKF_OPENEXIST)
            result = {}
            self.tree.exec_bs('bs_treedb_get_subkey_properties', [], [], result)
            for val in result.values():
                if 'GroupId' in val:
                    if val['GroupId'] in data:
                        raise ParamsError(_('该分组或下级分组下存在子网，请移动或删除子网后删除分组'))

        sub_path = company + '\\Net\\' + kwargs['id'] + '\\group'
        self.tree.open('Co', sub_path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        for id in data:
            self.tree.exec_tree('Treedb_DeleteSubKey', id)
            ModifyNetGroup(company, kwargs['id'], id, 1)
        return data

    # @modify
    def GroupIgnore(self, **kwargs):
        """
        网络组忽略
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        path = company + '\\Net\\' + kwargs['id']
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        data = self.GetGroup(company + '\\Net\\' + kwargs['id'], kwargs['groupId'])
        subnet = self.GetSubnet(company + '\\Net\\' + kwargs['id'], data)
        for id in data:
            sub_path = company + '\\Net\\' + kwargs['id'] + '\\group\\' + id
            self.tree.open('Co', sub_path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).delete()
        if subnet:
            for key in subnet:
                sub_path = company + '\\Net\\' + kwargs['id'] + '\\SubNet\\' + key
                self.tree.open('Co', sub_path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).insert_item(
                    'state', 1)
        return data

    # @modify
    def GetIpNetworkInfo(self, **kwargs):
        """
        获取IP网络数据
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        path = company + '\\Net'
        sub_key = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if company not in sub_key:
            return []
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": int(kwargs.get('state'))
        if kwargs.get('state') else 0,
                "vLiDataType": type_map['int']}]
        condition = '0'
        if 'label' in kwargs:
            label = kwargs['label']
            QIS.append({"name": "label", "nCondition": symbol_map['nclike'], "vLiData": '*' + label + '*',
                        "vLiDataType": type_map['str']})
            condition += ' and 1'
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, condition, key, 0, 0)
        result = {}
        if len(key) > 0:
            self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)
            for key, val in result.items():
                self.tree.exec_bs('bs_treedb_open_subkey', path + '\\' + key + '\\ts', TRDB_OPKF_OPENEXIST)
                subResult = {}
                self.tree.exec_bs('bs_treedb_get_subkey_properties', [], ['mxlabel'], subResult)
                mxlabels = [v['mxlabel'] for v in subResult.values()]
                val['tslabel'] = ','.join(mxlabels)
        return list(result.values())

    # @modify
    def GetNetworkOrGroupData(self, **kwargs):
        """
        获取指定网络或者分组数据
        :param kwargs:
        :return:
        """
        if kwargs['id'] == '' and 'state' in kwargs:
            return 0, list()
        company = self.GetCompany(**kwargs)
        path = company + '\\Net\\' + kwargs['id']
        keys = self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if 'SubNet' not in keys:
            return 0, list()
        data_dict = json.loads(GetGroupSubNetJson(company, kwargs['id']))
        print(data_dict)
        state = 0 if 'state' not in kwargs else int(kwargs['state'])
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": state, "vLiDataType": type_map['int']}]
        condition = '0'
        if 'GroupId' in kwargs:
            conditions = '('
            groups = self.GetGroup(company + '\\Net\\' + kwargs['id'], kwargs['GroupId'])
            for key, id in enumerate(groups):
                QIS.append({"name": "GroupId", "nCondition": symbol_map['e'], "vLiData": id,
                            "vLiDataType": type_map['str']})
                conditions += str(key + 1) + ' or '
            condition += ' and' + conditions[:-3] + ' )'
        # 查询子网IP
        if 'SubnetIp' in kwargs:
            QIS.append({"name": "SubnetIp", "nCondition": symbol_map['like'], "vLiData": '*' + kwargs['SubnetIp'] + '*',
                        "vLiDataType": type_map['str']})
            condition += 'and ' + str(len(QIS) - 1)
        # 查询子网名称
        if 'label' in kwargs:
            QIS.append({"name": "label", "nCondition": symbol_map['like'], "vLiData": '*' + kwargs['label'] + '*',
                        "vLiDataType": type_map['str']})
            condition += 'and ' + str(len(QIS) - 1)

        self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\SubNet', TRDB_OPKF_OPENEXIST)
        daataCount = self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, condition, [], 0, 0)
        size = (int(kwargs['page_index']) - 1) * int(kwargs['page_size'])
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition_ex', QIS, condition, key, int(kwargs['page_size']),
                          size, 'SubNetId', False)
        result = {}
        if len(key) > 0:
            self.tree.exec_bs('bs_treedb_get_subkey_properties', key, [], result)

        for key, val in result.items():
            val['network'] = kwargs['id']
            val['MaxIpCount'] = 0
            val['UsedBefore30'] = 0
            val['UsedIn30'] = 0
            val['UsedIpCount'] = 0
            val['NotUsedIpCount'] = 0
            val['SubnetIp'] = val['SubNetId'][0:val['SubNetId'].find('/')]
            if data_dict is None:
                continue
            for v in data_dict['subnet']:
                if v['id'] == key:
                    val['MaxIpCount'] = v['MaxIpCount']
                    val['UsedBefore30'] = v['UsedBefore30']
                    val['UsedIn30'] = v['UsedIn30']
                    val['UsedIpCount'] = v['UsedIpCount']
                    val['NotUsedIpCount'] = v['MaxIpCount'] - v['UsedIpCount']
        return daataCount, list(result.values())

    # @modify
    def GetrelationTs(self, **kwargs):
        """
        获取关联的TS
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        path = company + '\\Net'
        sub_key = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if company not in sub_key:
            return []
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        # QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
        #         "vLiDataType": type_map['int']}]
        # key = []
        # self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)
        result = {}
        ts = []
        self.tree.exec_bs('bs_treedb_get_subkey_properties', [], [], result)
        for val in result.values():
            try:
                if val['TsId'].find(';') != -1:
                    ts.extend(val['TsId'].split(';'))
                else:
                    ts.append(val['TsId'])
            except:
                continue
        return ts

    def up_search_group(self, group_id, group_data, result):
        """
        向上查询
        :param group_id: 组ID
        :param group_data:  组数据
        :return:
        """
        for key, val in group_data.items():
            if key == group_id:
                if key not in result:
                    result[key] = val
                self.up_search_group(val['parent'], group_data, result)

    def move_get_sub_group(self, group_dict, pid, sub_group, level):
        """

        :return:
        """
        for key, val in group_dict.items():
            if val['parent'] == pid:
                val['level'] = level + 1
                sub_group.append(val['level'])
                self.move_get_sub_group(group_dict, key, sub_group, val['level'])

    # @modify
    def move(self, **kwargs):
        """
        移动组或子网
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        path = company + '\\Net\\' + kwargs['id']
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        if kwargs['type'] == '1':
            QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                    "vLiDataType": type_map['int']}]
            self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\group', TRDB_OPKF_OPENEXIST)
            group_sub_key = []
            self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', group_sub_key, 0, 0)
            group_dict = dict()
            group_tmp_dict = dict()
            if group_sub_key:
                self.tree.exec_bs('bs_treedb_get_subkey_properties', [], [], group_dict)
                self.up_search_group(kwargs['toId'], group_dict, group_tmp_dict)
            sub_group = []
            self.move_get_sub_group(group_dict, kwargs['fromId'], sub_group, 1)
            sub_num = max(sub_group) if sub_group else 1
            if sub_num + len(group_tmp_dict) > 5:
                raise Exception(_('目录层级不能大于5'))
            self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\group\\' + kwargs['fromId'], TRDB_OPKF_OPENEXIST)
            self.tree.exec_bs('bs_treedb_insert_property', 'parent', kwargs['toId'], type_map['str'], True)
        elif kwargs['type'] == '2':
            self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\SubNet\\' + kwargs['fromId'], TRDB_OPKF_OPENEXIST)
            if kwargs['totype'] == '0':
                res_dict = {}
                self.tree.exec_bs('bs_treedb_get_properties', [], res_dict)
                if 'GroupId' in res_dict:
                    self.tree.exec_tree('Treedb_DeleteProperty', 'GroupId')
            elif kwargs['totype'] == '1':
                self.tree.exec_bs('bs_treedb_insert_property', 'GroupId', kwargs['toId'], type_map['str'], True)

    # @modify
    def GetIpNetnetCount(self, **kwargs):
        """
        获取IP子网数量
        :return:
        """
        company = self.GetCompany(**kwargs)
        sub_key = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if company not in sub_key:
            return list()
        self.tree.open('Co', company + '\\Net', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 0,
                "vLiDataType": type_map['int']}]
        key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', key, 0, 0)
        tmp = {}
        if key:
            for id in key:
                tmp[id] = {}
                data_dict = json.loads(GetGroupSubNetJson(company, id))

                if data_dict is None:
                    continue
                if 'subnet' not in data_dict:
                    continue
                for val in data_dict['subnet']:
                    tmp[id][val['id']] = {'UsedIpCount': val['UsedIpCount'], 'UnTrust': val['UnTrustIp']}
        return tmp

    # @modify
    def IgnoreTree(self, **kwargs):
        """
        忽略树
        :param kwargs:
        :return:
        """
        company = self.GetCompany(**kwargs)
        path = company + '\\Net'
        sub_key = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if company not in sub_key:
            return []
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 1,
                "vLiDataType": type_map['int']}]
        self.tree.open('Co', path, file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT)
        result = {}
        data = []
        self.tree.exec_bs('bs_treedb_get_subkey_properties', [], ['label', 'id'], result)
        for val in result.values():
            try:
                self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\' + val['id'], TRDB_OPKF_OPENEXIST)
            except:
                continue
            res_dict = {}
            self.tree.exec_bs('bs_treedb_get_properties', [], res_dict)
            keys = list()
            self.tree.exec_tree('Treedb_GetAllSubKeys', keys)
            if 'SubNet' in keys:
                self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\' + val['id'] + '\\SubNet',
                                    TRDB_OPKF_OPENEXIST)
                sub_key = []
                self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', sub_key, 0, 0)
                if sub_key:
                    data_dict = json.loads(GetGroupSubNetJson(company, val['id']))

                    if data_dict is None or 'subnet' not in data_dict:
                        data_dict = dict()
                    sub_result = {}
                    self.tree.exec_bs('bs_treedb_get_subkey_properties', sub_key, [], sub_result)
                    for k, v in sub_result.items():
                        for vt in data_dict['subnet']:
                            if k == vt['id']:
                                v['UsedIpCount'] = vt['UsedIpCount']
                    val['sub'] = list(sub_result.values())
                    data.append(val)
                else:
                    if res_dict['state'] == 1:
                        val['sub'] = list()
                        data.append(val)
            else:
                if res_dict['state'] == 1:
                    val['sub'] = list()
                    data.append(val)
        return data

    # @modify
    def ip_info(self, **kwargs):
        """
        获取指定IP数据
        :param kwargs:  参数字典
        :return:
        """
        scompany = self.GetCompany(**kwargs)
        path = scompany + '\\Net'
        sub_key_list = self.tree.open('Co', '', file='ipctrl', host=MxConfig.HOST, port=MxConfig.PORT).sub_keys()
        if scompany not in sub_key_list:
            return []
        self.tree.exec_tree('Treedb_ReopenSubKey', path, TRDB_OPKF_OPENEXIST)
        QIS = [{"name": "state", "nCondition": symbol_map['e'], "vLiData": 1,
                "vLiDataType": type_map['int']}]
        sub_key = []
        self.tree.exec_bs('bs_treedb_query_subkey_by_condition', QIS, '', sub_key, 0, 0)
        result = list()
        if sub_key:
            for key in sub_key:
                self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\' + key, TRDB_OPKF_OPENEXIST)
                ip_list = list()
                self.tree.exec_tree('Treedb_GetAllSubKeys', ip_list)
                if 'SubNet' in ip_list:
                    self.tree.exec_tree('Treedb_ReopenSubKey', path + '\\' + key + '\\SubNet', TRDB_OPKF_OPENEXIST)
                    subnet_list = list()
                    self.tree.exec_tree('Treedb_GetAllSubKeys', subnet_list)
                    result.append({'network': key, 'subnet': subnet_list})
        return result
